package cn.ynrcb.personnelfile.admin.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.ynrcb.personnelfile.admin.enums.AuditStatusEnum;
import cn.ynrcb.personnelfile.admin.entity.FileEntity;
import cn.ynrcb.personnelfile.admin.service.SmsService;
import cn.ynrcb.personnelfile.common.exception.MyException;
import cn.ynrcb.personnelfile.common.utils.ValidatorUtils;
import cn.ynrcb.personnelfile.sysadmin.entity.SysOrgEntity;
import cn.ynrcb.personnelfile.sysadmin.entity.SysUserEntity;
import cn.ynrcb.personnelfile.sysadmin.service.CurrentUserService;
import cn.ynrcb.personnelfile.sysadmin.service.SysOrgService;
import cn.ynrcb.personnelfile.sysadmin.service.SysUserRoleService;
import cn.ynrcb.personnelfile.sysadmin.service.SysUserService;
import cn.ynrcb.personnelfile.sysadmin.vo.AuditVo;
import cn.ynrcb.personnelfile.common.utils.PageUtils;
import cn.ynrcb.personnelfile.common.utils.Query;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.ynrcb.personnelfile.admin.dao.RegisterInfoDao;
import cn.ynrcb.personnelfile.admin.entity.RegisterInfoEntity;
import cn.ynrcb.personnelfile.admin.service.RegisterInfoService;
import org.springframework.transaction.annotation.Transactional;


@Service("registerInfoService")
public class RegisterInfoServiceImpl extends ServiceImpl<RegisterInfoDao, RegisterInfoEntity> implements RegisterInfoService {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysOrgService sysOrgService;
    @Autowired
    private SmsService smsService;
    @Autowired
    private CurrentUserService currentUserService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<RegisterInfoEntity> queryWrapper = new QueryWrapper();
        String key = Convert.toStr(params.get("key"));
        if (StringUtils.isNotEmpty(key)) {
            queryWrapper.like("org_name", key).or().like("credit_code", key).or().like("phone", key).or().like("contact_person", key);
        }
        Integer auditStatus = Convert.toInt(params.get("auditStatus"));
        if (ObjectUtil.isNotNull(auditStatus)) {
            queryWrapper.eq("audit_status", auditStatus);
        }
        queryWrapper.orderByDesc("creat_time");
        IPage<RegisterInfoEntity> page = this.page(
                new Query<RegisterInfoEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    public void saveFile(String id, String fileName, String filePath) {
        baseMapper.saveFile(id, fileName, filePath);
    }

    @Override
    public FileEntity getFileById(String id) {
        return baseMapper.getFileById(id);
    }

    @Override
    public void deleteByFileId(String id) {
        baseMapper.deleteByFileId(id);
    }

    @Override
    public void userRegister(RegisterInfoEntity registerInfo) {
        //验证手机号
        if (!ValidatorUtils.isMobile(registerInfo.getPhone())) {
            throw new MyException("该手机号不符合规则！");
        }
        //验证手机号是否注册过
        RegisterInfoEntity entityByPhone = this.getOne(new QueryWrapper<RegisterInfoEntity>()
                .eq("phone", registerInfo.getPhone())
        );
        if (ObjectUtil.isNotNull(entityByPhone)) {
            //注册过
            if (entityByPhone.getAuditStatus().equals(AuditStatusEnum.WAIT_AUDIT.getCode())) {
                //状态为待审核
                throw new MyException("该手机号已提交过注册信息，请耐心等待审核！");
            } else if (entityByPhone.getAuditStatus().equals(AuditStatusEnum.AUDIT_NO_PASS.getCode())) {
                //状态审核未通过
                throw new MyException("该手机号已注册，但审核未通过，请查看短信通知，并至登录页面的注册驳回处理页面进行处理。");
            } else {
                throw new MyException("该手机号已注册通过，请直接登录。");
            }
        }
        //验证手机号是否被绑定
        SysUserEntity userByPhone = sysUserService.getOne(new QueryWrapper<SysUserEntity>()
                .eq("mobile", registerInfo.getPhone())
                .ne("is_delete", 1)
        );
        if (ObjectUtil.isNotNull(userByPhone)) {
            //使用中
            throw new MyException("该手机号已被使用。");

        }
        //验证手机号是否作为用户username
        SysUserEntity userByUsername = sysUserService.getOne(new QueryWrapper<SysUserEntity>()
                .eq("username", registerInfo.getPhone())
                .ne("is_delete", 1)
        );
        if (ObjectUtil.isNotNull(userByUsername)) {
            //使用中
            throw new MyException("该手机号已被使用。");

        }
        //验证统一社会信用代码是否注册过
        RegisterInfoEntity entityByCreditCode = this.getOne(new QueryWrapper<RegisterInfoEntity>()
                .eq("credit_code", registerInfo.getCreditCode())
        );
        if (ObjectUtil.isNotNull(entityByCreditCode)) {
            //注册过
            if (entityByCreditCode.getAuditStatus().equals(AuditStatusEnum.WAIT_AUDIT.getCode())) {
                //状态为待审核
                throw new MyException("该统一社会信用代码已提交过注册信息，请耐心等待审核！");
            } else if (entityByCreditCode.getAuditStatus().equals(AuditStatusEnum.AUDIT_NO_PASS.getCode())) {
                //状态为待审核
                throw new MyException("该统一社会信用代码已注册，但审核未通过，请查看短信通知，并至登录页面的注册驳回处理页面进行处理。");
            } else {
                throw new MyException("该统一社会信用代码已注册通过，请直接登录。");
            }
        }
        //验证统一社会信用代码是否已使用
        SysOrgEntity orgByCreditCode = sysOrgService.getOne(new QueryWrapper<SysOrgEntity>()
                .eq("credit_code", registerInfo.getCreditCode())
                .ne("status", 1)
        );
        if (ObjectUtil.isNotNull(orgByCreditCode)) {
            throw new MyException("该统一社会信用代码已被使用。");
        }
        //验证密码规则
        if (!ValidatorUtils.checkPasswordRule(registerInfo.getPassword())) {
            throw new MyException("该密码不符合规则！");
        }
        //sha256加密
        String salt = RandomStringUtils.randomAlphanumeric(20);
        registerInfo.setPassword(new Sha256Hash(registerInfo.getPassword(), salt).toHex()); //密码加密
        registerInfo.setSalt(salt);
        this.save(registerInfo);
    }

    @Override
    @Transactional
    public Integer auditInfo(String[] idArry, AuditVo params) {
        Integer num = 0;
        List<String> ids = Arrays.asList(idArry);
        for (String id : ids) {
            //处理user信息
            RegisterInfoEntity info = this.getById(id);
            info.setAuditStatus(params.getAuditStatus());
            info.setAuditRemark(params.getRemark());
            info.setCoding(params.getCoding());
            info.setAuditUserId(currentUserService.getUserId());
            info.setAuditTime(new Date());
            this.updateById(info);
            num++;
            if (params.getAuditStatus().equals(AuditStatusEnum.AUDIT_NO_PASS.getCode())) {
                //如果审核不通过需要调用短信接口发送通知
                String content = "您注册的账号未审核通过，原因：" + params.getRemark() + "。请至昆明市整改需求系统系统：http://wxb.km.gov.cn/xjzbpdxt/#/login的登录页面进行注册驳回处理。";
                smsService.sendAuditSms(info.getPhone(), content.trim());
            } else if (params.getAuditStatus().equals(AuditStatusEnum.AUDIT_PASS.getCode())) {
                //如果审核通过，则将registerInfo数据转变为user数据和org数据
                SysOrgEntity org = new SysOrgEntity();
                org.setOrgName(info.getOrgName());
                org.setCreditCode(info.getCreditCode());
//                org.setAddress(info.getAddress());
//                org.setParentOrgName(info.getParentOrgName());
//                org.setIndustry(info.getIndustry());
//                org.setMobile(info.getMobile());
//                org.setFile(info.getFile());
                org.setCoding(info.getCoding());
                org.setOrgType(1);
                org.setPId(Long.valueOf(1));
                org.setRegion("530100"); //TODO 目前为固定地区为昆明市
                sysOrgService.saveOrg(org);
                SysUserEntity user = new SysUserEntity();
                user.setPassword(info.getPassword());
                user.setSalt(info.getSalt());
                user.setUsername(info.getPhone());
                user.setMobile(info.getPhone());
                user.setUserCnName(Convert.toStr(info.getContactPerson(), ""));
                user.setEmail(Convert.toStr(info.getEmail(), ""));
                List<Integer> roleIdList = new ArrayList<>();
                roleIdList.add(10);
                user.setRoleId(roleIdList.get(0));
                user.setRoleIdList(roleIdList); //TODO 目前为固定的协会人员roleId
                user.setOrgId(sysOrgService.getOne(new QueryWrapper<SysOrgEntity>().eq("credit_code", info.getCreditCode())).getId());
                sysUserService.save(user);
                SysUserEntity savedUser = sysUserService.getOne(new QueryWrapper<SysUserEntity>().eq("username", user.getUsername()));
                //保存用户与角色关系
                sysUserRoleService.saveOrUpdate(savedUser.getUserId(), user.getRoleIdList());
                //如果审核通过需要调用短信接口发送通知
                String content = "恭喜您，您注册的账号审核通过，您可至昆明市整改需求系统系统：http://wxb.km.gov.cn/xjzbpdxt/#/login登录进行操作。";
                smsService.sendAuditSms(info.getPhone(), content.trim());
            }
        }
        return num;
    }

}